//
// Created by zhengjuping on 24-9-12.
//

#include <mutex>
#include <cstring>
#include "esp_log.h"
#include "EnvIIGattCharacteristic.h"

#define TAG "EnvIIGattCharacteristic"

static const uint8_t defaultEnvValue[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

EnvIIGattCharacteristic::EnvIIGattCharacteristic() : GattCharacteristic(
        BleUuid(BleUuid::Width::UUID_16, 0xF101),
        defaultEnvValue,
        sizeof(defaultEnvValue),
        GattCharacteristic::ResponseMethod::RSP_BY_APP,
        GattCharacteristic::Properties::Read_Write_Notify,
        GattCharacteristic::Permissions::Read_Write) {
    _sensorManager = std::make_unique<SensorManager>();
    _sensorManager->registerObserver(this);
    _sensorManager->start(std::chrono::milliseconds(3000));
}

void EnvIIGattCharacteristic::onSensorValueUpdata(float temperature, float humidity, float pressure) {
    std::unique_lock<std::mutex> lock(_mutex);
    convertToEnvValue( temperature, humidity, pressure, _envValue );
    if( _isNotifyEnabled  ){
        sendIndicate( _envValue, sizeof(_envValue) );
    }
}


EnvIIGattCharacteristic::~EnvIIGattCharacteristic() {
    _sensorManager->stop();
    _sensorManager->unregisterObserver(this);
}

void EnvIIGattCharacteristic::onReadEvent(uint8_t *data, uint16_t &length) {
    std::unique_lock<std::mutex> lock(_mutex);
    memcpy(data, _envValue, sizeof(_envValue));
    length = sizeof(_envValue);
}

void EnvIIGattCharacteristic::onWriteEvent(const uint8_t *data, uint16_t length) {
    uint16_t u16Data = data[0] | (data[1] << 8);
    ESP_LOGE(TAG, "onWriteEvent: %x", u16Data);
}

void EnvIIGattCharacteristic::onNotifyStatusUpdateEvent(bool notifyEnabled) {

}

void EnvIIGattCharacteristic::convertToEnvValue(float temperature,
                                                float humidity,
                                                float pressure,
                                                uint8_t *envValue) const {

    auto i16Temperature = (int16_t)(temperature * 100);
    auto i16Humidity = (int16_t)(humidity * 100);
    auto i32Pressure = (int32_t)(pressure * 100);

    envValue[0] = i16Temperature >> 8;
    envValue[1] = i16Temperature & 0xFF;

    envValue[2] = i16Humidity >> 8;
    envValue[3] = i16Humidity & 0xFF;

    envValue[4] = i32Pressure >> 24;
    envValue[5] = (i32Pressure >> 16) & 0xFF;
    envValue[6] = (i32Pressure >> 8) & 0xFF;
    envValue[7] = i32Pressure & 0xFF;
}

void EnvIIGattCharacteristic::onNotify(bool enable) {
    std::unique_lock<std::mutex> lock(_mutex);
    _isNotifyEnabled = enable;
}

